#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

#include <vector>

void usage()
{
    fprintf(stderr,
            "usage: prog IP_ADDRESS PORT TEXT\n"
            "example ./udp_echo_client 127.0.0.1 7 \"Hello World!\"\n");
}

int main(int argc, char **argv)
{
    if(argc < 4)
    {
        usage();
        exit(1);
    }

    const char *address = argv[1];
    short port = htons(atoi(argv[2]));
    const char *text = argv[3];


    int fd;
    struct sockaddr_in server_address;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0)
    {
        fprintf(stderr, strerror(errno));
        exit(1);
    }

    server_address.sin_family = AF_INET;
    struct hostent *h = gethostbyname(address);
    if(h == NULL)
    {
        fprintf(stderr, strerror(errno));
        exit(1);
    }

    memcpy(&server_address.sin_addr, h->h_addr, sizeof(server_address.sin_addr));
    server_address.sin_port = port;
    size_t length = strlen(text);
    int result = sendto(fd, text, length, 0, (const struct sockaddr *)&server_address, sizeof(server_address));
    if(result  < 0)
    {
        fprintf(stderr, strerror(errno));
        exit(1);
    }

    socklen_t address_length = 0;
    memset(&server_address, 0, sizeof(server_address));
    std::vector<unsigned char> reply(8192);
    result = recvfrom(fd, &reply.at(0), reply.size(), 0, (struct sockaddr *)&server_address, &address_length);
    if(result  < 0)
    {
        fprintf(stderr, strerror(errno));
        exit(1);
    }
    reply.resize(result);
    if(result == length && memcmp(text, &reply.at(0), length) == 0)
    {
        printf("OK\n");
    }
    else
    {
        printf("FAILED\n");
    }
    close(fd);
    return 0;
}
